package com.myk.game.gobangchess.ai.shock;

public class Find_possible_solve {

    public static int[] find_possible_solve(int[][] board, int playerTurn) {
        int[][] modifiedBoard = multiplyMatrix(board, playerTurn);

        int[][] convKernel = {{1, 1, 1, 1}};
        int[][] convResult = conv2(modifiedBoard, convKernel);

        int yMin, yMax, xMin, xMax;

        if (anyGreaterThanOrEqual(convResult, 3)) {
            int[] indices = findIndices(convResult, 3);
            int yInitial = indices[0];
            int xInitial = indices[1];

            yMin = Math.max(yInitial - 2, 0);
            yMax = Math.min(yInitial + 2, 7);
            xMin = Math.max(xInitial - 3, 0);
            xMax = Math.min(xInitial + 6, 7);
        } else {
            convKernel = new int[][]{{1}, {1}, {1}, {1}};
            convResult = conv2(modifiedBoard, convKernel);

            if (anyGreaterThanOrEqual(convResult, 3)) {
                int[] indices = findIndices(convResult, 3);
                int yInitial = indices[0];
                int xInitial = indices[1];

                yMin = Math.max(yInitial - 3, 0);
                yMax = Math.min(yInitial + 6, 7);
                xMin = Math.max(xInitial - 2, 0);
                xMax = Math.min(xInitial + 2, 7);
            } else {
                yMin = 0;
                yMax = 7;
                xMin = 0;
                xMax = 7;
            }
        }

        return new int[]{yMin, yMax, xMin, xMax};
    }

    private static int[][] multiplyMatrix(int[][] matrix, int scalar) {
        int rows = matrix.length;
        int cols = matrix[0].length;
        int[][] result = new int[rows][cols];

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                result[i][j] = matrix[i][j] * scalar;
            }
        }

        return result;
    }

    private static int[][] conv2(int[][] board, int[][] kernel) {
        int numRows = board.length;
        int numCols = board[0].length;
        int kernelRows = kernel.length;
        int kernelCols = kernel[0].length;
        int[][] result = new int[numRows - kernelRows + 1][numCols - kernelCols + 1];

        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result[0].length; j++) {
                int sum = 0;
                for (int m = 0; m < kernelRows; m++) {
                    for (int n = 0; n < kernelCols; n++) {
                        sum += board[i + m][j + n] * kernel[m][n];
                    }
                }
                result[i][j] = sum;
            }
        }

        return result;
    }

    private static boolean anyGreaterThanOrEqual(int[][] matrix, int threshold) {
        for (int[] row : matrix) {
            for (int value : row) {
                if (value >= threshold) {
                    return true;
                }
            }
        }
        return false;
    }

    private static int[] findIndices(int[][] matrix, int value) {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if (matrix[i][j] == value) {
                    return new int[]{i, j};
                }
            }
        }
        return null;
    }
}
